#include "ReadConfig.h"
#include "json.hpp"
#include <iostream>
#include <string>
#include <algorithm>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
using namespace std;
using json =  nlohmann::json;

int main()
{
    ReadConfig reader("../conf/config.ini");
    string ip = reader.parseConfig("ip");
    string port = reader.parseConfig("port");
    
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    addr.sin_port = htons(atoi(port.c_str()));
    
    connect(socketfd, (struct sockaddr *)&addr, sizeof(addr));

    while(1){
        string type;
        int ID = 0;
        cout << "请选择服务：输入 1 进入关键词推荐服务，输入 2 进入网页查询服务" << "\n";
        getline(cin, type);
        if(cin.eof()){
            cout << "结束输入，退出程序\n";
            break;
        }
        if(type == "1"){
            ID = 1;
        }
        else if(type == "2"){
            ID = 2;
        }
        else{
            cout << "请重新输入正确的数字！\n";
            continue;
        }
        cout << "请输入要查询的内容：\n";
        string msg;
        //cin, getline会在读取到换行符时自动丢弃
        getline(cin, msg);
        if(cin.eof()){
            cout << "结束输入，退出程序\n";
            break;
        }
        
        //判断输入是否有效
        string temp = msg;
        //将输入复制给一个临时变量，去掉临时变量左边的空字符和右边的空字符
        temp.erase(temp.begin(), find_if(temp.begin(), temp.end(), [](unsigned char ch) { return !isspace(ch); }));
        temp.erase(find_if(temp.rbegin(), temp.rend(), [](unsigned char ch) { return !isspace(ch); }).base(), temp.end());
        //剩余的字符串长度为0说明输入的全是空字符
        if(temp.empty()){
            cout << "输入不能是空行或仅包含空格，请重新输入！\n";
            continue;
        }

        //发送消息
        size_t sendSize = msg.size();
        /* cout << "send: " << sendSize << " " << ID << " " << msg << "\n"; */
        send(socketfd, &sendSize, sizeof(size_t), 0); //发送消息内容的长度
        send(socketfd, &ID, sizeof(int), 0);          //发送消息id
        send(socketfd, msg.c_str(), msg.size(), 0);   //发送消息内容
        
        //接收消息
        size_t recvSize = 0;
        int ret  = recv(socketfd, &recvSize, sizeof(size_t), MSG_WAITALL);
        if(ret == 0){
            cout << "服务端断开连接\n";
            break;
        }
        int id = 0;
        recv(socketfd, &id, sizeof(int), MSG_WAITALL); //接收消息内容的长度
        
        char *buf = new char[recvSize + 1](); //小括号不能省略否则申请的空间有可能不会初始化
        recv(socketfd, buf, recvSize, MSG_WAITALL); //接收消息内容
        string jsonStr(buf);
        delete [] buf;
        
        /* cout << "jsonStr: " << jsonStr << endl; */
        /* cout << "jsonStr size: " << jsonStr.size() << endl; */
        
        json j = json::parse(jsonStr);
        if(j.empty()){
            cout << "查询结果为空！\n";
            continue;
        }
        vector<string> result = j["data"].get<vector<string>>();
        if(id == 1){
            cout << "候选词推荐结果：\n";
            for(auto &i: result){
                cout << i << " ";
            }
            cout << "\n";
        }
        else{
            cout << "网页搜索结果：\n";
            for(auto &i:result){
                json doc = json::parse(i);
                cout << doc["title"].get<string>() << "\n";
                cout << doc["url"].get<string>() << "\n";
                cout << doc["tops"].get<string>() << "\n";
                cout << doc["content"].get<string>() << "\n";
            }
        }
    }

    close(socketfd);
    return 0;
}

